﻿using ArtMath.Resource;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;

namespace ArtMath.Converter
{
    public abstract class EnumConverterBase : TypeConverterBase
    {
        protected Type EnumType;
        protected HashSet<object> ShieldValues;
        public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
        {
            return true;
        }
        public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            ArrayList objs = new ArrayList();
            foreach (object item in Enum.GetValues(EnumType))
            {
                if (ShieldValues != null && ShieldValues.Contains(item)) continue;
                objs.Add(item);
            }
            return new StandardValuesCollection(objs);
        }
        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            string str = value as string;
            if (str != null)
            {
                Array arr = Enum.GetValues(EnumType);
                foreach (object item in arr)
                {
                    if (ShieldValues != null && ShieldValues.Contains(item)) continue;
                    if (str.Equals(translateEnumValue(item), StringComparison.OrdinalIgnoreCase))
                    {
                        return item;
                    }
                }
                return arr.GetValue(0);
            }
            return base.ConvertFrom(context, culture, value);
        }
        string translateEnumValue(object obj)
        {
            if (!Resources.TryTranslate(obj.ToString(), out string res))
            {
                if (!Resources.TryTranslate($"{EnumType.Name}.{obj}", out res))
                {
                    res = obj.ToString();
                }
            }
            return res;
        }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (value != null)
            {
                if (value.GetType() == EnumType)
                {
                    if (destinationType == typeof(string))
                    {
                        if (ShieldValues != null && ShieldValues.Contains(value))
                        {
                            return string.Empty;
                        }
                        return translateEnumValue(value);
                    }
                    else if (destinationType == typeof(InstanceDescriptor))
                    {
                        return new InstanceDescriptor(EnumType.GetConstructor(
                            new Type[] { typeof(string) }),
                            new string[] { value.ToString() });
                    }
                }
                else
                {
                    return value.ToString();
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
        public Dictionary<object, string> GetEnumValuesAndNames()
        {
            Dictionary<object, string> dic = new Dictionary<object, string>();
            foreach (object item in Enum.GetValues(EnumType))
            {
                if (ShieldValues != null && ShieldValues.Contains(item)) continue;
                dic.Add(item, translateEnumValue(item));
            }
            return dic;
        }
    }
}
